// (c) 2008 Kickstone Technology Ltd

#pragma once
#include "resource.h"       // main symbols
#include "DDButton.h"
#include "HtmlWindowEventCallback.h"
#include "WebBrowserEventCallback.h"

#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif

#include   <iostream>   
#include   <stdlib.h>   
#include   <fstream>  
using namespace std;

class CHtmlWindowEventSink;
class CWebBrowserEventSink;
class CIEWindow;

class ATL_NO_VTABLE CButtonDemoBHO :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CButtonDemoBHO, &CLSID_ButtonDemoBHO>,
	public IObjectWithSiteImpl<CButtonDemoBHO>,
	public IDispatchImpl<IButtonDemoBHO, &IID_IButtonDemoBHO, &LIBID_DDButtonLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
	public IOleCommandTarget,
	public IHtmlWindowEventCallback,
	public IWebBrowserEventCallback
{
public:
	//static int cnt =0;
	CButtonDemoBHO() {
		this->isInjected=false;
		ATLTRACE("\n - CButtonDemoBHO::CButtonDemoBHO()");

	}
	~CButtonDemoBHO() {
		ATLTRACE("\n - CButtonDemoBHO::~CButtonDemoBHO()");
	}

	DECLARE_REGISTRY_RESOURCEID(IDR_BUTTONDEMOBHO)

	DECLARE_NOT_AGGREGATABLE(CButtonDemoBHO)

	BEGIN_COM_MAP(CButtonDemoBHO)
		COM_INTERFACE_ENTRY(IButtonDemoBHO)
		COM_INTERFACE_ENTRY(IDispatch)
		COM_INTERFACE_ENTRY(IObjectWithSite)
		COM_INTERFACE_ENTRY(IOleCommandTarget)
	END_COM_MAP()



	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct();
	void FinalRelease();

	// IOleObjectWithSite Method
	STDMETHOD(SetSite)(IUnknown *pUnkSite);

	// IOleCommandTarget functions
	// we use this to trigger the goblin when the data has downloaded
	STDMETHOD(QueryStatus)(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText);
	STDMETHOD(Exec)(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, VARIANTARG* pvaOut);


	// DWebBrowserEvents2 event handlers
	HRESULT onBeforeNavigate2(IDispatch *pDisp, VARIANT *vUrl, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel);
	HRESULT onNavigateComplete2(IDispatch *pDisp, VARIANT *vUrl);
	HRESULT onDownloadBegin();
	HRESULT onDocumentComplete(IDispatch *pDisp, VARIANT *vUrl);
	HRESULT onQuit();
	HRESULT onWindowStateChanged(DWORD dwFlags, DWORD dwValidFlagsMask);


	// Browser Event handler callback
	void releaseBrowserSink();

	// button callback
	void buttonPressed();
	void menuPressed();

	// IWindowHandlerCallback functions
	void onLoadOccured();
	void onUnloadOccured(){}
	void releasePointer();


private:

	// general purpose internal member variables
	CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> m_spWebBrowser2;



	HWND m_hWnd;
	CIEWindow *m_ieWindow;

	// general purpose internal member functions
	void getHWND();
	bool isMainFrame(IDispatch *pDisp);
	void setWindowHandler();

	// event handlers
	CWebBrowserEventSink *m_browserEventSink;
	CHtmlWindowEventSink *m_htmlWindowEventSink;

	// used to track if page refresh or not.
	bool m_normalPageLoad;
	CString m_lastURL;



	// used to handle interfaces across threads
	CComPtr<IGlobalInterfaceTable> m_spTable;
	DWORD m_interfaceTableCookie;
	DWORD m_threadID;

public:
	HRESULT readJs(LPCTSTR path,CComBSTR &js)
	{
		//CComBSTR myJs=(CComBSTR)js;
		fstream   fin;
		fin.open(path,ios::in);   
		if(!fin)   
		{   
			ATLTRACE("error:file1.txt   can   not   open!\t");   
			return S_OK;
		}   
		
		const int LINE_LENGTH = 100000; 
		char str[LINE_LENGTH];  
		
		int count;
		count=0;
		while(fin.getline(str,LINE_LENGTH)){
			count++;
			CComBSTR line=CComBSTR(str);
			js.AppendBSTR(line);
		}   
		fin.close();   
		return S_OK;
	}

	HRESULT	getCurrentURL(CComBSTR &url);

	bool	isTianyaPostPage();
	bool	isInjected;

	HRESULT	injectScript(CComBSTR &path);

	HRESULT	getInstallPath(CComBSTR &path);
	HRESULT	getPackagesPath(CComBSTR &path);
	
};

OBJECT_ENTRY_AUTO(__uuidof(ButtonDemoBHO), CButtonDemoBHO)
